/******************************************************************************

	COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2010.

	This file is part of Maxsi Engine.

	Maxsi Engine is free software: you can redistribute it and/or modify it
	under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or (at your
	option) any later version.

	Maxsi engine is distributed in the hope that it will be useful, but WITHOUT
	ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
	FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
	for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with Maxsi Engine. If not, see <http://www.gnu.org/licenses/>.

	MaxsiEngine.dll
	A general purpose C++ library for the Maxsi Technology Project.

	MaxsiWindowSystem.cpp
	A powerful UI System abstraction layer that allows the same UI code to run
	on any platform that implements a Maxsi Window System.

******************************************************************************/

#include "MaxsiEngine.h"

BeginMaxsiNamespace

LINK MaxsiWindowSystem* CreateLocalWindowSystem()
{	
	#if defined(Maxsi_Support_W32)
	
		return new MaxsiWindowSystemW32;

	#elif defined(Maxsi_Support_GTK)
	
		return new MaxsiWindowSystemGTK;

	#else
		
		#error "There is no implemented Window System in use on your target platform!"

		return NULL;

	#endif
}

LINK bool DeleteLocalWindowSystem(MaxsiWindowSystem* WindowSystem)
{
	delete WindowSystem;

	return true;
}

LINK int CriticalMsgBox(MaxsiHandle Parent, int Flags, MESTR* ErrorMessage, MESTR* ErrorTitle)
{
	MAXSI_REMOVE_ME();
	MESTRPRINTF(_MESTR("%S: Error: %S\n"), ErrorTitle, ErrorMessage);

	#ifdef WIN32
	
		return MessageBoxM((HWND)Parent, ErrorMessage, ErrorTitle, MB_OK | MB_ICONEXCLAMATION);

	#elif defined(Maxsi_Using_GTK)

		if ( gtk_init_check(NULL, NULL) )	
		{
			// Create an error dialog.
			GtkWidget* Dialog = gtk_message_dialog_new((GtkWindow*)NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%S", ErrorTitle);

			if ( Dialog == NULL ) { return 0; }

			gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(Dialog), "%S", ErrorMessage);

			// Display the error dialog and wait for it to close.
			gtk_dialog_run(GTK_DIALOG(Dialog));

			// Delete the error dialog when it has been closed.
			gtk_widget_destroy(Dialog);

			return 1;
		}
		else
		{
			MESTRPRINTF(_MESTR("%S"), _MESTR("Critical Error: Could not initialize GTK+!"));
			return 0;
		}

	#else
	
		return 0;	

	#endif
}

MaxsiWindowSystem::MaxsiWindowSystem()
{
	ControlSystem	=	NULL;
}

MaxsiWindowSystem::~MaxsiWindowSystem()
{
	
}

MaxsiControlSystem* MaxsiWindowSystem::GetControlSystem()
{
	if ( !ControlSystem )
	{
		ControlSystem	=	CreateControlSystem();
	}

	return ControlSystem;
}

MaxsiWindow::MaxsiWindow()
{
	Window			=	NULL;
	Frame			=	NULL;

	Width			=	0;
	Height			=	0;

	MyWindowSystem	=	NULL;
}

MaxsiWindow::~MaxsiWindow()
{
	
}

MaxsiWindowSystem* MaxsiWindow::WindowSystem()
{
	return MyWindowSystem;
}

MaxsiControlSystem* MaxsiWindow::ControlSystem()
{
	if ( MyWindowSystem == NULL ) { return false; }
	return MyWindowSystem->GetControlSystem();
}

MaxsiWindowSystem* MaxsiControlSystem::WindowSystem()
{
	return MyWindowSystem;
}

bool MaxsiControlSystem::SetWindowSystem(MaxsiWindowSystem* NewWindowSystem)
{
	MyWindowSystem	=	NewWindowSystem;
	return true;
}

bool MaxsiWindow::SetWindowSystem(MaxsiWindowSystem* NewWindowSystem)
{
	// Check if we already have a window system, as we are not able to switch between window
	// systems just yet. That's on the todo list!

	if ( MyWindowSystem ) { return false; }	

	MyWindowSystem = NewWindowSystem;

	return true;
}

bool MaxsiWindow::CreateWindow(int WindowWidth, int WindowHeight)
{
	bool	Result			=	true;

	if (!WindowSystem()) { return false; }

	if ( WindowWidth == 0 ) { WindowWidth = GetDefaultWidth(); }
	if ( WindowHeight == 0 ) { WindowHeight = GetDefaultHeight(); }

	if (!Window)
	{
		MESTR*	WindowTitle		=	GetWindowTitle();

		Width	=	WindowWidth;
		Height	=	WindowHeight;

		Window	=	WindowSystem()->CreateWindow(NULL, Width, Height, Maxsi_Window_CenterX, Maxsi_Window_CenterY, WindowTitle);

		delete[] WindowTitle;

		if ( Window )
		{
			Frame	=	ControlSystem()->CreateFrame(Window);

			if ( !CreateControls() || !UpdateWindow() ) { return false; }

			WindowSystem()->ShowWindow(Window);
	
			return true;
		}
		else
		{
			return false;
		}
	}
	
	return Result;
}

bool MaxsiWindow::DeleteWindow()
{
	return true;
}

bool MaxsiWindow::UpdateWindow()
{
	// Todo, update the title of the window too!

	UpdateWindowIcon(); // The icon is non-critical, so its presense does not affect this function.

	return UpdateControls();
}

bool MaxsiWindow::CreateControls()
{
	return true;
}

bool MaxsiWindow::DeleteControls()
{
	return true;
}

bool MaxsiWindow::UpdateControls()
{
	return true;
}

MESTR* MaxsiWindow::GetWindowTitle()
{
	return BuildString(1, _MESTR("Maxsi Window System Powered Application"));
}

int MaxsiWindow::GetDefaultWidth()
{
	return 500;
}

int MaxsiWindow::GetDefaultHeight()
{
	return 370;
}

bool MaxsiWindow::UpdateWindowIcon()
{
	return true;
}

int MaxsiWindow::MoveWindow(MaxsiHandle Control, int Top, int Left, int Width, int Height, bool UnusedInLinux)
{
	MESTRPRINTF(_MESTR("Updating control %p to T=%i, L=%i, W=%i, H=%i\n"), Control, Top, Left, Width, Height);
	return WindowSystem()->MoveWindowControl(Frame, Control, Top, Left, Width, Height, UnusedInLinux);
}

EndMaxsiNamespace


